package com.vegetable.modules.service.finance.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vegetable.modules.entity.baseData.AddressBook;
import com.vegetable.modules.entity.baseData.InvoiceInfo;
import com.vegetable.modules.entity.baseData.InvoiceItem;
import com.vegetable.modules.entity.baseData.po.InvoiceQueryPO;
import com.vegetable.modules.entity.baseData.po.InvoiceUpdatePO;
import com.vegetable.modules.mapper.finance.InvoiceInfoMapper;
import com.vegetable.modules.service.baseData.IAddressBookService;
import com.vegetable.modules.service.baseData.IInvoiceItemService;
import com.vegetable.modules.service.finance.IInvoiceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 财务收款管理 服务实现类
 * </p>
 *
 * @author wangruijie
 * @since 2024-04-13
 */
@Slf4j
@Service
public class InvoiceServiceImpl extends ServiceImpl<InvoiceInfoMapper, InvoiceInfo> implements IInvoiceService {
    @Resource
    private IAddressBookService addressBookService;
    
    @Resource
    private IInvoiceItemService invoiceItemService;

    @Override
    public int saveInvoice(InvoiceInfo invoiceInfo) {
        // 保存发票基本信息
        int result = baseMapper.insertInvoiceInfo(invoiceInfo);
        
        // 保存发票商品明细
        saveInvoiceItems(invoiceInfo);
        
        return result;
    }
    
    /**
     * 保存发票商品明细
     * @param invoiceInfo 发票信息
     */
    private void saveInvoiceItems(InvoiceInfo invoiceInfo) {
        try {
            // 获取商品明细信息
            List<InvoiceInfo.RowWord> commodityNames = invoiceInfo.getCommodityName();
            if (commodityNames != null && !commodityNames.isEmpty()) {
                List<InvoiceItem> invoiceItems = commodityNames.stream().map(rowWord -> {
                    InvoiceItem item = new InvoiceItem();
                    item.setInvoiceId(invoiceInfo.getId());
                    item.setRowNum(Integer.parseInt(rowWord.getRow()));
                    item.setCommodityName(rowWord.getWord());
                    
                    // 设置其他商品明细信息（如果存在）
                    setCommodityDetailInfo(item, invoiceInfo, rowWord.getRow());
                    
                    return item;
                }).collect(Collectors.toList());
                
                // 批量保存商品明细
                invoiceItemService.saveBatch(invoiceItems);
            }
        } catch (Exception e) {
            log.error("保存发票商品明细失败，发票ID: {}", invoiceInfo.getId(), e);
        }
    }
    
    /**
     * 设置商品明细信息
     * @param item 商品明细实体
     * @param invoiceInfo 发票信息
     * @param rowNum 行号
     */
    private void setCommodityDetailInfo(InvoiceItem item, InvoiceInfo invoiceInfo, String rowNum) {
        // 设置商品类型
        if (invoiceInfo.getCommodityType() != null) {
            invoiceInfo.getCommodityType().stream()
                .filter(type -> type != null && type.contains(":" + rowNum + ":"))
                .findFirst()
                .ifPresent(type -> item.setCommodityType(type.split(":")[0]));
        }
        
        // 设置商品单位
        if (invoiceInfo.getCommodityUnit() != null) {
            invoiceInfo.getCommodityUnit().stream()
                .filter(unit -> unit != null && unit.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(unit -> item.setCommodityUnit(unit.getWord()));
        }
        
        // 设置商品数量
        if (invoiceInfo.getCommodityNum() != null) {
            invoiceInfo.getCommodityNum().stream()
                .filter(num -> num != null && num.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(num -> item.setCommodityNum(num.getWord()));
        }
        
        // 设置商品单价
        if (invoiceInfo.getCommodityPrice() != null) {
            invoiceInfo.getCommodityPrice().stream()
                .filter(price -> price != null && price.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(price -> {
                    try {
                        item.setCommodityPrice(new java.math.BigDecimal(price.getWord()));
                    } catch (NumberFormatException e) {
                        log.warn("商品单价格式错误: {}", price.getWord());
                    }
                });
        }
        
        // 设置商品金额
        if (invoiceInfo.getCommodityAmount() != null) {
            invoiceInfo.getCommodityAmount().stream()
                .filter(amount -> amount != null && amount.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(amount -> {
                    try {
                        item.setCommodityAmount(new java.math.BigDecimal(amount.getWord()));
                    } catch (NumberFormatException e) {
                        log.warn("商品金额格式错误: {}", amount.getWord());
                    }
                });
        }
        
        // 设置商品税率
        if (invoiceInfo.getCommodityTaxRate() != null) {
            invoiceInfo.getCommodityTaxRate().stream()
                .filter(taxRate -> taxRate != null && taxRate.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(taxRate -> item.setCommodityTaxRate(taxRate.getWord()));
        }
        
        // 设置商品税额
        if (invoiceInfo.getCommodityTax() != null) {
            invoiceInfo.getCommodityTax().stream()
                .filter(tax -> tax != null && tax.getRow().equals(rowNum))
                .findFirst()
                .ifPresent(tax -> {
                    try {
                        item.setCommodityTax(new java.math.BigDecimal(tax.getWord()));
                    } catch (NumberFormatException e) {
                        log.warn("商品税额格式错误: {}", tax.getWord());
                    }
                });
        }
        
        // 设置商品车辆类型
        if (invoiceInfo.getCommodityVehicleType() != null) {
            invoiceInfo.getCommodityVehicleType().stream()
                .filter(vehicleType -> vehicleType != null && vehicleType.contains(":" + rowNum + ":"))
                .findFirst()
                .ifPresent(vehicleType -> item.setCommodityVehicleType(vehicleType.split(":")[0]));
        }
        
        // 设置商品车牌号码
        if (invoiceInfo.getCommodityPlateNum() != null) {
            invoiceInfo.getCommodityPlateNum().stream()
                .filter(plateNum -> plateNum != null && plateNum.contains(":" + rowNum + ":"))
                .findFirst()
                .ifPresent(plateNum -> item.setCommodityPlateNum(plateNum.split(":")[0]));
        }
    }

    @Override
    public Map<String, Object> list(InvoiceQueryPO po) {
        Map<String, Object> result = new HashMap<>();
        IPage<InvoiceInfo> iPage = new Page<>(po.getCurrentPage(), po.getPageSize());
//        QueryWrapper<InvoiceInfo> wrapper = new QueryWrapper<>();
//        wrapper.select("sum(total_amount) as totalAmount");
//        wrapper.like(StrUtil.isNotBlank(po.getSellerName()), "seller_name", po.getSellerName());
//        wrapper.like(StrUtil.isNotBlank(po.getPurchaserName()), "purchaser_name", po.getPurchaserName());
//        wrapper.eq(ObjectUtil.isNotNull(po.getTotalAmount()), "total_amount", po.getTotalAmount());
//        wrapper.eq(ObjectUtil.isNotNull(po.getAbId()), "ab_id", po.getAbId());
//        if(ObjectUtil.isNotNull(po.getStartTime())){
//            wrapper.gt("invoice_date", DateUtil.beginOfDay(po.getStartTime()));
//        }
//        if(ObjectUtil.isNotNull(po.getEndTime())){
//            wrapper.lt( "invoice_date", DateUtil.endOfDay(po.getEndTime()));
//        }
//        Map<String, Object> amountMap = this.getMap(wrapper);
//        double totalAmount = amountMap != null ? (Double) amountMap.get("totalAmount") : 0d;

        IPage<InvoiceInfo> invoicePage = baseMapper.selectInvoiceWithAddressBook(iPage, po);
        Double totalAmount = baseMapper.selectInvoiceTotalAmountWithAddressBook(po);
        result.put("totalAmount", totalAmount);
        result.put("invoicePage", invoicePage);
        return result;
    }

    @Override
    public Integer updateInvoiceBelong(InvoiceUpdatePO po) throws Exception {
        Integer effectRow = 0;
        InvoiceInfo exist = baseMapper.selectById(po.getId());
        if(ObjectUtil.isNull(exist)){
            log.error("需要修改的发票信息不存在：{}", JSONObject.toJSONString(po));
            throw new RuntimeException("需要修改的发票信息不存在");
        }
        AddressBook ab = addressBookService.queryById(po.getAbId());
        if(ObjectUtil.isNull(ab)){
            log.error("账户信息不存在：{}", JSONObject.toJSONString(po));
            throw new RuntimeException("账户信息不存在");
        }
        Integer staffType = ab.getStaffType();
        // 1代表客商
        String bankName = staffType == 1 ? exist.getPurchaserName() : exist.getSellerName();
        String bankNo = staffType == 1 ? exist.getPurchaserBankAccount() : exist.getSellerBankAccount();
        String bankNoMark = staffType == 1 ? "purchaser_name" : "seller_name";
        // 待更新实体
        InvoiceInfo updater = new InvoiceInfo();
        if(po.getEffectAllFlow() && StrUtil.isNotBlank(bankName)){
            // 如果true 则把符合卡号的发票全部归属于该ab
            updater.setAbId(po.getAbId());
            updater.setAbName(ab.getNoteName());
            com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<InvoiceInfo> wrapper = new com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<>();
            wrapper.eq(bankNoMark, bankName);
            effectRow = baseMapper.update(updater, wrapper);
        }else{
            // 更新发票的归属id
            BeanUtils.copyProperties(po, updater);
            updater.setAbName(ab.getNoteName());
            effectRow = baseMapper.updateById(updater);
        }
        // 更新归属的常用银行账号
        // 银行卡号现在通过BankCard实体管理，此处逻辑已移除

        return effectRow;
    }
    
    /**
     * 根据ID查询发票详情（包含商品明细）
     * @param id 发票ID
     * @return 发票信息
     */
    @Override
    public InvoiceInfo getInvoiceDetailById(Long id) {
        // 通过关联查询直接获取发票详情（包含商品明细）
        return baseMapper.selectInvoiceDetailById(id);
    }
}